/*
 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     bstefanescu
 */
package org.nuxeo.gwt.habyt.app.client;

import org.nuxeo.gwt.habyt.invocation.client.ObjectRef;
import org.nuxeo.gwt.habyt.invocation.client.Referenceable;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
 * 
 */
public abstract class View extends Composite implements
        ValueChangeHandler<String> {

    protected HandlerRegistration hreg;

    public View() {
        initWidget(createWidget());
    }

    @Override
    protected void onLoad() {
        hreg = History.addValueChangeHandler(this);
    }

    @Override
    protected void onUnload() {
        if (hreg != null) {
            hreg.removeHandler();
        }
    }

    /**
     * Get the active input of this view (i.e. the last referenceable object
     * opened in this view). May return null.
     * 
     * @return
     */
    public abstract Referenceable getActiveInput();

    /**
     * Open the given input reference.
     * 
     * @param ref
     */
    public abstract void doOpen(Referenceable ref);

    /**
     * Create the underlying widget
     * 
     * @return
     */
    protected abstract Widget createWidget();

    /**
     * Get the view ID. for view loaded from templates this is the element ID.
     * 
     * @return
     */
    public String getId() {
        return getElement().getId();
    }

    public void open(Referenceable ref) {
        // manage history
        String token = null;
        if (ref == null) {
            token = getId() + ':';
        } else {
            token = getId() + ':' + ref.getRef().toString();
        }
        History.newItem(token, false);
        doOpen(ref);
    }

    @Override
    public void onValueChange(ValueChangeEvent<String> event) {
        String token = event.getValue();
        String prefix = getId() + ':';
        if (token.startsWith(prefix)) {
            token = token.substring(prefix.length());
            ObjectRef ref = new ObjectRef(token);
            Referenceable input = getActiveInput();
            if (input != null && !ref.sameAs(input.getRef())) {
                open(ref);
            }
        }
    }
}
